home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 October / Macworld (1998-10).dmg / Shareware World / Info / For Developers / MacZoop 1.8.4 / More Classes / File Classes / ZBlockFile.h < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-22  |  4.8 KB  |  161 lines  |  [TEXT/CWIE]

  1. /*************************************************************************************************
  2. *
  3. *
  4. *            ObjectMacZapp        -- a standard Mac OOP application template
  5. *
  6. *
  7. *
  8. *            ZBlockFile.h        -- a generic file object that includes some basic block
  9. *                                    management facilities. This type of file is useful for
  10. *                                    implementing VM schemes and databases, etc.
  11. *
  12. *
  13. *            © 1996, Graham Cox
  14. *
  15. *
  16. *
  17. *
  18. *************************************************************************************************/
  19.  
  20. #pragma once
  21.  
  22. #ifndef __ZBLOCKFILE__
  23. #define __ZBLOCKFILE__
  24.  
  25.  
  26. #include    "ZFile.h"
  27.  
  28.  
  29. class    ZArray;
  30.  
  31.  
  32. class    ZBlockFile    : public ZFile
  33. {
  34. protected:
  35.     ZArray*        bmap;
  36.     long        refSeed;
  37.     long        useCount;
  38.     
  39. public:
  40.     ZBlockFile( const FSSpec& aFileSpec );
  41.     ZBlockFile( Str255 fName );
  42.     ~ZBlockFile();
  43.     
  44. // overrides:
  45.  
  46.     virtual void            Open();
  47.     virtual void            Close();
  48.     
  49. // specific to this class:
  50.     
  51.     virtual long            AddBlock();
  52.     virtual void            AddBlockUsingRef( const long aRef );
  53.     virtual void            RemoveBlock( const long ref );
  54.  
  55.     virtual void            GetBlockData( const long ref, void* dataPtr, long* dataLen );
  56.     virtual void            GetBlockData( const long ref, Handle dataH );
  57.     
  58.     virtual void            SetBlockData( const long ref, void* dataPtr, long dataLen );
  59.     virtual void            SetBlockData( const long ref, Handle dataH );
  60.     
  61.     virtual long            GetNewRefSeed() { return ++refSeed; };
  62.     virtual long            GetBlockCount();
  63.     virtual long            GetBlock( const long ref );
  64.     virtual long            GetBlockRef( const long bkIndex );
  65.     virtual unsigned long    GetBlockSize( const long bkIndex );
  66.  
  67. protected:
  68.     
  69.     virtual void            AppendBlock( const long ref, const unsigned long sizeNeeded );
  70.     virtual long            FindFreeBlock( const unsigned long sizeNeeded );
  71.     virtual void            FreeBlock( const long bkIndex );
  72.     virtual void            SplitBlock( const long bkIndex, const unsigned long bkSize );
  73.     virtual void            ReallocBlock( const long ref, long newBkSize );
  74.     virtual void            SetMarkToBlock( const long bkIndex );
  75.     
  76.     virtual void            ReadMap() {};
  77.     virtual void            WriteMap() {};
  78.     virtual void            InitMap();
  79.     virtual void            WriteHeader() {};
  80.     
  81.     virtual void            CompactMap();
  82.     virtual void            CompactFile() {};
  83. };
  84.  
  85. // we force 68k alignment for when the map is stored in the file- the file will work
  86. // on either platform.
  87.  
  88. #if PRAGMA_ALIGN_SUPPORTED
  89. #pragma options align=mac68k
  90. #endif
  91.  
  92. // block status:
  93.  
  94. typedef enum
  95. {
  96.     free,
  97.     notFree
  98. }
  99. BlockStatus;
  100.  
  101. // this is what is stored in the <bmap> array, one for every block in the file:
  102.  
  103. typedef struct
  104. {
  105.     long            fRefNum;
  106.     unsigned long    fMark;
  107.     unsigned long    fSize;
  108.     BlockStatus        fStatus;
  109. }
  110. Block;
  111.  
  112. #if PRAGMA_ALIGN_SUPPORTED
  113. #pragma options align=reset
  114. #endif
  115.  
  116. // possible errors:
  117.  
  118. enum
  119. {
  120.     kBlockFileNotOpenErr    = 257,
  121.     kBlockBadRefErr,
  122.     kBlockNotFoundErr,
  123.     kBlockDupRefErr,
  124.     kBadSplitReqErr
  125. };
  126.  
  127. /*
  128.  
  129. This object is a file which is subdivided into a sequence of multiple blocks. This is useful
  130. when you want to store in a single file a lot of different things. Each item in the file must
  131. have a unique "block reference number", which can be allocated sequentially from a seed if
  132. you desire. Otherwise, for temporary files, you could use an object address- as long as the
  133. value is unique it doesn't matter. You can then get and set the block's data at any time- this
  134. object looks after where it is stored in the file. Before you can do this, you must register
  135. the block refnum using AddBlock(). This creates an entry in the map table referring to this
  136. block. If you no longer need the block, calling RemoveBlock() will free the space in the file
  137. for other's use.
  138.  
  139. If you want to use this class for permanent files, the map itself must be saved in the file
  140. and recovered when it is opened. To do this, you must override WriteHeader, WriteMap and
  141. ReadMap. The header should generally include an offset to the start of the map so that you can
  142. read it back into memory.
  143.  
  144. The methods in this object manage the filespace reasonably efficiently, but never split data
  145. into non-contiguous segments. Thus the file will grow but not automatically shrink (though
  146. freed space is always re-used where possible for new data). To shrink the file, you can call
  147. CompactFile(), which will remove all unused space. This may take a while due to the amount of
  148. data movement needed on disk, and uses a progress bar. CompactMap() is a much faster operation
  149. which conjoins all adjacent free blocks into larger ones, thus making the reuse of such parts
  150. of the file much more likely. This is called internally and you shouldn't need to call it
  151. yourself.
  152.  
  153. This object makes no assumptions whatever about the data you store- as long as you supply its
  154. total size in bytes, it will store and return it to you. You are free to change the size once
  155. the block is written- the position within the file where the data is saved is automatically
  156. managed so that you can always retrieve it and that freed space becomes available for new data.
  157.  
  158. */
  159.  
  160.  
  161. #endif